/*
 * MODULE  NAME  :
 * PROGRAM NAME  : tkapp.h
 * AUTHOR        : hotmocha(hotmocha@126.com)
 * CREATE  DATE  : 2015-10-21 15:04:46
 * PROGRAM DESC  :
 *
 * HISTORY       :
 *
 */
#ifndef _H_TKAPP_H_
#define _H_TKAPP_H_

#ifndef _FUNCTION_
	#define _FUNCTION_
#endif

#include "tkevent.h"
#include "list.h"

struct tk_message {
	int header_left_len;			/* had received or sent head len */
	char header[HEADERLEN + 1];	/* (4: len, 4: type) total 8 bytes*/
	int message_type;

	int body_len;		/* should send or recv body len */
	int body_left_len;	/* left send or recv body len */
	char body[MAXMESSAGELEN + 1];
};

#if 0
#define tk_message_buffer(p_tk_msg, p_tk_msg_buffer, p_tk_msg_len)  		\
	do { 									\
		p_tk_msg_buffer = &((p_tk_msg)->body); 				\
		p_tk_msg_len = p_tk_msg->body_len; 				\
	} while(0);
#endif 

#define TK_MESSAGE_INFO(tmsg) 							\
	do { 									\
		struct tk_message *_tmsg_ = tmsg; 				\
		dlog("-------------- tk_msg info --------------"); 		\
		dlog("header_left_len[%d] - header[%s]", _tmsg_->header_left_len, _tmsg_->header); 				\
		dlog("body_len[%d] - body_left_len[%d] - body[\n%s\n]", _tmsg_->body_len, _tmsg_->body_left_len, _tmsg_->body); 	\
	} while (0);


#define TK_CONNECT_SYNC_CLIENT_INFO		0
#define TK_CONNECT_SYNC_CLIENT_INFO_DONE	1
#define TK_CONNECT_SYNC_CLIENTS_LIST		2
#define TK_CONNECT_SYNC_CLIENTS_LIST_DONE	3
#define TK_CONNECT_COMMUNICATING		4

struct tk_handler_param {
        event_handler handler;
        int handlerType;        /* 1:r 2:w 4:rw */
        void* data;
};

struct tk_connect {
	void *client_ptr;	/* point to struct member(only for server) */
	int stage;		

	struct custom_socket *csock;
	struct tk_message send_msg[MAXMESSAGENUM];
	struct tk_handler_param handlerParam;
	int msg_start;	/* to send */
	int msg_end; 	/* to recv */
	
	struct tk_message recv_msg;

        int finished:1;
        int failed:1;
        int recving_head:1;
        int recving_body:1;
        int sending_head:1;
        int sending_body:1;

	struct list_head list_node;
};

/******************   function start *********************/
/**
create tk_connect and bind tk_connect to custom_socket
@RETURN
	1. tk_connect*
	2. NULL
**/
struct tk_connect* get_tk_connect(struct custom_socket *s);
void destory_tk_connect(struct select_env *env, struct tk_connect *conn);

/**
init tk_message with body buffer 
@RETURN
	1. TK_TOO_LONG_MESSAGE
	2. TK_OK
**/
int set_tk_message_header(struct tk_message *msg, int body_len, int type);

int tk_do_add_send_msg(struct custom_socket *s, struct tk_message *send_msg);
int tk_do_send_msg(struct custom_socket *s);
int tk_do_recv_msg(struct custom_socket *s);
	
void tk_start_communicate(struct tk_connect *conn);
int tk_remote_close(struct select_env *env, struct tk_connect *conn);
	
struct tk_connect* tk_connect_server(struct select_env *env, char *ip, int serverport);
struct tk_message* get_send_message(struct tk_connect *conn);
struct tk_message* get_recv_message(struct tk_connect *conn);
int tk_message_body_len(struct tk_message *msg);
int tk_message_type(struct tk_message *msg);

#endif
